﻿using CoreShop.Library;
using CoreShop.Model;
using CoreShop.Model.UI;
using CoreShop.Services;
using IWshRuntimeLibrary;
using Microsoft.AspNetCore.SignalR.Client;
using Newtonsoft.Json;
using SqlSugar.Extensions;
using Sunny.UI;
using System;
using System.Collections;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.AxHost;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace CoreShop.App
{
    /// <summary>
    /// signalR客户端（与云服务器的通讯）
    /// </summary>
    public partial class fpgSignalMonitor : UIPage
    {
        private HubConnection conn1 { get; set; }
        static System.Timers.Timer timer_conn = null;
        private int iTime_conn = 0;

        public fpgSignalMonitor()
        {
            InitializeComponent();

            if (timer_conn == null)
            {
                timer_conn = new System.Timers.Timer();
                timer_conn.Interval = 1000;
                timer_conn.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
                timer_conn.Enabled = true;
            }
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                timer_conn.Enabled = false;
                iTime_conn = iTime_conn + 1;

                if (iTime_conn % 10 == 0)
                {
                    btn_CheckConn(null, null);
                }

                if (iTime_conn % 60 == 0)
                {
                    CheckConnFromSevice();
                    iTime_conn = 0;
                }

            }
            catch { }
            finally
            {
                timer_conn.Enabled = true;
            }
        }

        private async Task<bool> SetLinkToHost()
        {
            try
            {
                SetMessageLog("【连接开始】");

                if (conn1 != null)
                {
                    //await conn1.StopAsync();
                     conn1.DisposeAsync();
                }
                conn1 = null;
                conn1 = SignaRlHelp.GetConnection(txt_channel.Text);
                await conn1.StartAsync();
                //被服务器端调用
                conn1.On<string>("CallByServer", (string msg) =>
                {
                    BeginInvoke(new MethodInvoker(() =>
                    {
                        try
                        {
                            if (txt_receive.TextLength > 5000) txt_receive.Clear();
                            txt_receive.Text += ($"{msg}");
                            SetReceiveMessage(msg);
                        }
                        catch (Exception)
                        {
                        }
                    }));
                });

                txt_id.Text = conn1.ConnectionId;
                SignalRUser user = new SignalRUser();
                user.connectionId = conn1.ConnectionId;
                user.storeId = text_store.Text;
                ClientMessage message = new ClientMessage();
                message.type = "userInfo";
                message.content = JsonConvert.SerializeObject(user);
                //连接成功后通知服务端写入用户信息
                await conn1.InvokeAsync<string>("CallByClient", $"{JsonConvert.SerializeObject(message)}");

                lblLinkState.Text = "正常";
                return true;
            }
            catch (Exception ex)
            {
                SetMessageLog("【连接失败】" + ex.Message);
                this.lblLinkState.Invoke(new Action(() => {
                    lblLinkState.Text = "异常"; 
                }));                
                return false;
            }
        }

        private async void btnLinkToHost_Click(object sender, System.EventArgs e)
        {
            await SetLinkToHost();
        }
                
        private void SetMessageLog(string msg)
        {
            try
            {
                string msgLog = DateTime.Now.ToString() + ":" + msg + "\r\n";
                this.txtMessageBox.Invoke(new Action(() => {
                    this.txtMessageBox.AppendText(msgLog);
                }));
            }
            catch (Exception)
            {
            }
        }

        private async void LoadPara()
        {
            var systemsetup = new corecmssystemsetupService().SelectDataFirst();
            txt_channel.Text = AppConstVars.sysUser.channel.ToString();
            if (systemsetup != null)
            {
                text_store.Text = systemsetup.storeId.ToString();
                await SetLinkToHost(); 
                pnlOpration.Visible = false;
            }            
        }

        private void LoadSignalClient()
        {
            //被服务器端调用
            //conn1.On<string>("CallByServer", (string msg) =>
            //{
            //    BeginInvoke(new MethodInvoker(() =>
            //    {
            //        try
            //        {
            //            if (txt_receive.TextLength > 5000) txt_receive.Clear();
            //            txt_receive.Text += ($"{msg}");
            //            SetReceiveMessage(msg);
            //        }
            //        catch (Exception)
            //        {
            //        }
            //    }));
            //});
        }

        private void SetReceiveMessage(string json)
        {
            try
            {
                var frombody = JsonConvert.DeserializeObject<FromBodyModel>(json);
                var msgLog = "【" + EnumHelper.GetDescByValue<GlobalEnumVars.MessageCode>(frombody.code) + "】" + json;
                var bl = SignalClientServices.ReceiveMessage(frombody);
                if (bl) msgLog += "【成功】";
                else msgLog += "【失败】";
                SetMessageLog(msgLog);
            }
            catch
            {
            }
        }

        private void txtCommand_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (txtCommand.Text == "cmd")
                {
                    pnlOpration.Visible = true;
                }
                else if (string.IsNullOrEmpty(txtCommand.Text))
                {
                    pnlOpration.Visible = false;
                }
            }
        }

        private void fpgSignalMonitor_ReceiveParams(object sender, UIPageParamsArgs e)
        {
            LoadPara();
            LoadSignalClient();
        }

        private void btnNewLink_Click(object sender, EventArgs e)
        {
            var frm = new frmSignalClientMessage();
            frm.ShowDialog();
            frm.Dispose();

            //button4_Click(null,null);
        }

        private async void btn_CheckConn(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(conn1.ConnectionId))
                {
                    SetMessageLog("【断网重连开始】");
                    await SetLinkToHost();
                    return;
                }
                var state = conn1.State.ToString();
                if (state != "Connected")
                {
                    await SetLinkToHost(); 
                }                
                //var ret = await conn1.InvokeAsync<string>("CallByClientWithReturnValue", $"{txt_senMsg.Text}");
                //txt_receive.Text = ret;
            }
            catch (Exception ex)
            {
                txt_receive.Text = ex.Message;
            }
        }

        /// <summary>
        /// 检查客户端和服务端的连接情况
        /// </summary>
        private async void CheckConnFromSevice()
        {
            bool bLinkFlag = false;
            try
            {
                if (string.IsNullOrEmpty(conn1.ConnectionId))
                {
                    SetMessageLog("【断网重连开始】");
                    await SetLinkToHost();
                    return;
                }
                SignalRUser user = new SignalRUser();
                user.connectionId = conn1.ConnectionId;
                user.storeId = text_store.Text;
                ClientMessage message = new ClientMessage();
                message.type = "userInfo";
                message.content = JsonConvert.SerializeObject(user);
                //连接成功后通知服务端写入用户信息
                bLinkFlag = true;
                var ret = await conn1.InvokeAsync<string>("CallByClientReturn", $"{JsonConvert.SerializeObject(message)}");
                bLinkFlag = false;
                //txt_receive.Text = ret;
            }
            catch (Exception ex)
            {
                SetMessageLog("【发送测试连接异常】" + ex.Message);
                bLinkFlag = true;
                //txt_receive.Text = ex.Message;
            }
            if (bLinkFlag)
            {
                SetMessageLog("【断网重连开始】");
                await SetLinkToHost();
                return;
            }
        }

        private string GetCorehubPara(int code, string sign, object data)
        {
            Hashtable htPara = new Hashtable();
            htPara["msgId"] = "";
            htPara["userId"] = AppConstVars.sysUser.id;
            htPara["storeId"] = AppConstVars.sysUser.storeId;
            htPara["code"] = code;
            htPara["msg"] = "";
            htPara["data"] = data;
            htPara["status"] = 0;
            htPara["sign"] = sign;
            return JsonConvert.SerializeObject(htPara);
        }

        private void btnTryConn_Click(object sender, EventArgs e)
        {
            if (AppConstVars.sysUser == null)
            {
                SetMessageLog("【登录失败】");
                return;
            }
            Thread newThread = new Thread(() => SetSignalPost());
            newThread.Start();            
        }

        private void SetSignalPost()
        {
            try
            {
                SetMessageLog("【连接测试】");
                string corehubUrl = AppConstVars.systemsetup.corehubUrl;
                if (string.IsNullOrEmpty(corehubUrl)) corehubUrl = "http://corehub.posyun3721.com";
                string postUrl = AppConstVars.systemsetup.corehubUrl + "/Interface/OnLogin";
                string password = Security.Decrypt(AppConstVars.sysUser.passWord);
                var data = new { AppConstVars.sysUser.userName, password };
                string postStr = JsonConvert.SerializeObject(data);
                string retStr =HttpHelper.httpPost(postUrl, postStr);
                AdminUiCallBack res = JsonConvert.DeserializeObject<AdminUiCallBack>(retStr);
                SetMessageLog("【提示】" + res.msg +":"+ retStr);
                if (res.code != 0)
                {
                    this.lblLinkState.Invoke(new Action(() => { lblLinkState.Text = "异常"; }));
                    return;
                }
                //postStr = GetCorehubPara((int)GlobalEnumVars.MessageCode.Code107, res.sign, new { foodTypeId = 0, name = "" });
                postStr = GetCorehubPara((int)GlobalEnumVars.MessageCode.Code143, res.sign, new { user = 0, name = "" });
                postUrl = corehubUrl + "/Interface/Reverse";
                retStr = HttpHelper.httpPost(postUrl, postStr);
                res = JsonConvert.DeserializeObject<AdminUiCallBack>(retStr);
                if (res.status != 0)
                {
                    SetMessageLog("【发送参数】" + postStr);
                    SetMessageLog("【返回信息】" + res.msg);
                    this.lblLinkState.Invoke(new Action(() => { lblLinkState.Text = "异常"; }));
                    return;
                }
                SetMessageLog("【返回成功】" + res.data.ToString());
                this.lblLinkState.Invoke(new Action(() => { lblLinkState.Text = "正常"; }));
            }
            catch (Exception ex)
            {
                SetMessageLog("【提交错误】" + ex.Message);
            }
        }

        private void btnClearLog_Click(object sender, EventArgs e)
        {
            try
            {                
                this.txtMessageBox.Invoke(new Action(() => {
                    this.txtMessageBox.Clear();
                }));
            }
            catch (Exception)
            {
            }
        }
    }
}